home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Applications / P4⁄Mac 2.0d4 / Mac source 2.0 / block1.p < prev    next >
Encoding:
Text File  |  1996-09-28  |  24.5 KB  |  1,107 lines  |  [TEXT/PJMM]

  1. {P4/Mac port by Ingemar Ragnemalm 1994-1996}
  2.  
  3. unit block1;
  4.  
  5. interface
  6.     uses
  7.         Messages, pcom1;
  8.  
  9. {procedures that used to be sub-procedures to block.}
  10.     var
  11.         lsy: p_symbol;
  12.         test: boolean;
  13. {Parameters to block:}
  14. {fsys: setofsys;}
  15. {fsy: symbol;}
  16. {fprocp: ctp;}
  17.  
  18.     procedure skip (fsys: setofsys);
  19.     procedure Bconstant (fsys: setofsys; var fsp: stp; var fvalu: valu);
  20.     function equalbounds (fsp1, fsp2: stp): boolean;
  21.     function comptypes (fsp1, fsp2: stp): boolean;
  22.     function isString (fsp: stp): boolean;
  23.     procedure typ (fsys: setofsys; var fsp: stp; var fsize: addrrange);
  24.     procedure labeldeclaration (fsys: setofsys); {FIX!!!}
  25.     procedure constdeclaration (fsys: setofsys); {FIX!!!}
  26.     procedure typedeclaration (fsys: setofsys); {FIX!!!}
  27.     procedure vardeclaration (fsys: setofsys); {FIX!!!}
  28.  
  29. implementation
  30.  
  31.     procedure skip (fsys: setofsys);
  32.       (*skip input string until relevant symbol found*)
  33.     begin
  34.         if not eof(input) then
  35.             begin
  36.                 while not (sy in fsys) and (not eof(input)) do
  37.                     insymbol;
  38.                 if not (sy in fsys) then
  39.                     insymbol
  40.             end
  41.     end; (*skip*)
  42.  
  43.     procedure Bconstant (fsys: setofsys; var fsp: stp; var fvalu: valu);
  44.         var
  45.             lsp: stp;
  46.             lcp: ctp;
  47.             sign: (none, pos, neg);
  48.             lvp: csp;
  49.             i: 2..strglgth;
  50.     begin
  51.         lsp := nil;
  52.         fvalu.ival := 0;
  53.         if not (sy in constbegsys) then
  54.             begin
  55.                 error(50);
  56.                 skip(fsys + constbegsys)
  57.             end;
  58.         if sy in constbegsys then
  59.             begin
  60.                 if sy = stringconst then
  61.                     begin
  62.                         if lgth = 1 then
  63.                             lsp := charptr
  64.                         else
  65.                             begin
  66.                                 new(lsp, arrays);
  67.                                 with lsp^ do
  68.                                     begin
  69.                                         aeltype := charptr;
  70.                                         inxtype := nil;
  71.                                         size := lgth * charsize;
  72.                                         form := arrays
  73.                                     end
  74.                             end;
  75.                         fvalu := val;
  76.                         insymbol
  77.                     end
  78.                 else
  79.                     begin
  80.                         sign := none;
  81.                         if (sy = addop) and (op in [plus, minus]) then
  82.                             begin
  83.                                 if op = plus then
  84.                                     sign := pos
  85.                                 else
  86.                                     sign := neg;
  87.                                 insymbol
  88.                             end;
  89.                         if sy = ident then
  90.                             begin
  91.                                 searchid([konst], lcp);
  92.                                 with lcp^ do
  93.                                     begin
  94.                                         lsp := idtype;
  95.                                         fvalu := values
  96.                                     end;
  97.                                 if sign <> none then
  98.                                     if lsp = intptr then
  99.                                         begin
  100.                                             if sign = neg then
  101.                                                 fvalu.ival := -fvalu.ival
  102.                                         end
  103.                                     else if lsp = realptr then
  104.                                         begin
  105.                                             if sign = neg then
  106.                                                 begin
  107.                                                     new(lvp, reel);
  108.                                                     if fvalu.valp^.rval[1] = '-' then
  109.                                                         lvp^.rval[1] := '+'
  110.                                                     else
  111.                                                         lvp^.rval[1] := '-';
  112.                                                     for i := 2 to strglgth do
  113.                                                         lvp^.rval[i] := fvalu.valp^.rval[i];
  114.                                                     fvalu.valp := lvp;
  115.                                                 end
  116.                                         end
  117.                                     else
  118.                                         error(105);
  119.                                 insymbol;
  120.                             end
  121.                         else if sy = intconst then
  122.                             begin
  123.                                 if sign = neg then
  124.                                     val.ival := -val.ival;
  125.                                 lsp := intptr;
  126.                                 fvalu := val;
  127.                                 insymbol
  128.                             end
  129.                         else if sy = realconst then
  130.                             begin
  131.                                 if sign = neg then
  132.                                     val.valp^.rval[1] := '-';
  133.                                 lsp := realptr;
  134.                                 fvalu := val;
  135.                                 insymbol
  136.                             end
  137.                         else
  138.                             begin
  139.                                 error(106);
  140.                                 skip(fsys)
  141.                             end
  142.                     end;
  143.                 if not (sy in fsys) then
  144.                     begin
  145.                         error(6);
  146.                         skip(fsys)
  147.                     end
  148.             end;
  149.         fsp := lsp
  150.     end; (*Bconstant*)
  151.  
  152.     function equalbounds (fsp1, fsp2: stp): boolean;
  153.         var
  154.             lmin1, lmin2, lmax1, lmax2: integer;
  155.     begin
  156.         if (fsp1 = nil) or (fsp2 = nil) then
  157.             equalbounds := true
  158.         else
  159.             begin
  160.                 getbounds(fsp1, lmin1, lmax1);
  161.                 getbounds(fsp2, lmin2, lmax2);
  162.                 equalbounds := (lmin1 = lmin2) and (lmax1 = lmax2)
  163.             end
  164.     end; (*equalbounds*)
  165.  
  166.     function comptypes (fsp1, fsp2: stp): boolean;
  167.       (*decide whether structures pointed at by fsp1 and fsp2 are compatible*)
  168.         var
  169.             nxt1, nxt2: ctp;
  170.             comp: boolean;
  171.             ltestp1, ltestp2: testp;
  172.     begin
  173.         if fsp1 = fsp2 then
  174.             comptypes := true
  175.         else if (fsp1 <> nil) and (fsp2 <> nil) then
  176.             if fsp1^.form = fsp2^.form then
  177.                 case fsp1^.form of
  178.                     scalar: 
  179.                         comptypes := false;
  180.         (* identical scalars declared on different levels are}
  181. {         not recognized to be compatible*)
  182.                     subrange: 
  183.                         comptypes := comptypes(fsp1^.rangetype, fsp2^.rangetype);
  184.                     pointer: 
  185.                         begin
  186.                             comp := false;
  187.                             ltestp1 := globtestp;
  188.                             ltestp2 := globtestp;
  189.                             while ltestp1 <> nil do
  190.                                 with ltestp1^ do
  191.                                     begin
  192.                                         if (elt1 = fsp1^.eltype) and (elt2 = fsp2^.eltype) then
  193.                                             comp := true;
  194.                                         ltestp1 := lasttestp
  195.                                     end;
  196.                             if not comp then
  197.                                 begin
  198.                                     new(ltestp1);
  199.                                     with ltestp1^ do
  200.                                         begin
  201.                                             elt1 := fsp1^.eltype;
  202.                                             elt2 := fsp2^.eltype;
  203.                                             lasttestp := globtestp
  204.                                         end;
  205.                                     globtestp := ltestp1;
  206.                                     comp := comptypes(fsp1^.eltype, fsp2^.eltype)
  207.                                 end;
  208.                             comptypes := comp;
  209.                             globtestp := ltestp2
  210.                         end;
  211.                     power: 
  212.                         comptypes := comptypes(fsp1^.elset, fsp2^.elset);
  213.                     arrays: 
  214.                         begin
  215.                             comp := comptypes(fsp1^.aeltype, fsp2^.aeltype) and comptypes(fsp1^.inxtype, fsp2^.inxtype);
  216.                             comptypes := comp and (fsp1^.size = fsp2^.size) and equalbounds(fsp1^.inxtype, fsp2^.inxtype)
  217.                         end;
  218.                     records: 
  219.                         begin
  220.                             nxt1 := fsp1^.fstfld;
  221.                             nxt2 := fsp2^.fstfld;
  222.                             comp := true;
  223.                             while (nxt1 <> nil) and (nxt2 <> nil) do
  224.                                 begin
  225.                                     comp := comp and comptypes(nxt1^.idtype, nxt2^.idtype);
  226.                                     nxt1 := nxt1^.next;
  227.                                     nxt2 := nxt2^.next
  228.                                 end;
  229.                             comptypes := comp and (nxt1 = nil) and (nxt2 = nil) and (fsp1^.recvar = nil) and (fsp2^.recvar = nil)
  230.                         end;
  231.         (*identical records are recognized to be compatible}
  232. {         iff no variants occur*)
  233.                     files: 
  234.                         comptypes := comptypes(fsp1^.filtype, fsp2^.filtype)
  235.                 end (*case*)
  236.             else (*fsp1^.form <> fsp2^.form*)
  237.                 if fsp1^.form = subrange then
  238.                     comptypes := comptypes(fsp1^.rangetype, fsp2)
  239.                 else if fsp2^.form = subrange then
  240.                     comptypes := comptypes(fsp1, fsp2^.rangetype)
  241.                 else
  242.                     comptypes := false
  243.         else
  244.             comptypes := true
  245.     end; (*comptypes*)
  246.  
  247. {"isString" used to be "string", which is reserved in Think Pascal.}
  248. {Is isString a proper name?}
  249. {/Ingemar}
  250.     function isString (fsp: stp): boolean;
  251.     begin
  252.         isString := false;
  253.         if fsp <> nil then
  254.             if fsp^.form = arrays then
  255.                 if comptypes(fsp^.aeltype, charptr) then
  256.                     isString := true
  257.     end; (*isString*)
  258.  
  259.     procedure typ (fsys: setofsys; var fsp: stp; var fsize: addrrange);
  260.         var
  261.             lsp, lsp1, lsp2: stp;
  262.             oldtop: disprange;
  263.             lcp: ctp;
  264.             lsize, displ: addrrange;
  265.             lmin, lmax: integer;
  266.  
  267.         procedure simpletype (fsys: setofsys; var fsp: stp; var fsize: addrrange);
  268.             var
  269.                 lsp, lsp1: stp;
  270.                 lcp, lcp1: ctp;
  271.                 ttop: disprange;
  272.                 lcnt: integer;
  273.                 lvalu: valu;
  274.         begin
  275.             fsize := 1;
  276.             if not (sy in simptypebegsys) then
  277.                 begin
  278.                     error(1);
  279.                     skip(fsys + simptypebegsys)
  280.                 end;
  281.             if sy in simptypebegsys then
  282.                 begin
  283.                     if sy = lparent then
  284.                         begin
  285.                             ttop := top;   (*decl. consts local to innermost block*)
  286.                             while display[top].occur <> blck do
  287.                                 top := top - 1;
  288.                             new(lsp, scalar, declared);
  289.                             with lsp^ do
  290.                                 begin
  291.                                     size := intsize;
  292.                                     form := scalar;
  293.                                     scalkind := declared
  294.                                 end;
  295.                             lcp1 := nil;
  296.                             lcnt := 0;
  297.                             repeat
  298.                                 insymbol;
  299.                                 if sy = ident then
  300.                                     begin
  301.                                         new(lcp, konst);
  302.                                         with lcp^ do
  303.                                             begin
  304.                                                 name := id;
  305.                                                 idtype := lsp;
  306.                                                 next := lcp1;
  307.                                                 values.ival := lcnt;
  308.                                                 klass := konst
  309.                                             end;
  310.                                         enterid(lcp);
  311.                                         lcnt := lcnt + 1;
  312.                                         lcp1 := lcp;
  313.                                         insymbol
  314.                                     end
  315.                                 else
  316.                                     error(2);
  317.                                 if not (sy in fsys + [comma, rparent]) then
  318.                                     begin
  319.                                         error(6);
  320.                                         skip(fsys + [comma, rparent])
  321.                                     end
  322.                             until sy <> comma;
  323.                             lsp^.fconst := lcp1;
  324.                             top := ttop;
  325.                             if sy = rparent then
  326.                                 insymbol
  327.                             else
  328.                                 error(4)
  329.                         end
  330.                     else
  331.                         begin
  332.                             if sy = ident then
  333.                                 begin
  334.                                     searchid([types, konst], lcp);
  335.                                     insymbol;
  336.                                     if lcp^.klass = konst then
  337.                                         begin
  338.                                             new(lsp, subrange);
  339.                                             with lsp^, lcp^ do
  340.                                                 begin
  341.                                                     rangetype := idtype;
  342.                                                     form := subrange;
  343.                                                     if isString(rangetype) then
  344.                                                         begin
  345.                                                             error(148);
  346.                                                             rangetype := nil
  347.                                                         end;
  348.                                                     min := values;
  349.                                                     size := intsize
  350.                                                 end;
  351.                                             if sy = colon then
  352.                                                 insymbol
  353.                                             else
  354.                                                 error(5);
  355.                                             Bconstant(fsys, lsp1, lvalu);
  356.                                             lsp^.max := lvalu;
  357.                                             if lsp^.rangetype <> lsp1 then
  358.                                                 error(107)
  359.                                         end
  360.                                     else
  361.                                         begin
  362.                                             lsp := lcp^.idtype;
  363.                                             if lsp <> nil then
  364.                                                 fsize := lsp^.size
  365.                                         end
  366.                                 end (*sy = ident*)
  367.                             else
  368.                                 begin
  369.                                     new(lsp, subrange);
  370.                                     lsp^.form := subrange;
  371.                                     Bconstant(fsys + [colon], lsp1, lvalu);
  372.                                     if isString(lsp1) then
  373.                                         begin
  374.                                             error(148);
  375.                                             lsp1 := nil
  376.                                         end;
  377.                                     with lsp^ do
  378.                                         begin
  379.                                             rangetype := lsp1;
  380.                                             min := lvalu;
  381.                                             size := intsize
  382.                                         end;
  383.                                     if sy = colon then
  384.                                         insymbol
  385.                                     else
  386.                                         error(5);
  387.                                     Bconstant(fsys, lsp1, lvalu);
  388.                                     lsp^.max := lvalu;
  389.                                     if lsp^.rangetype <> lsp1 then
  390.                                         error(107)
  391.                                 end;
  392.                             if lsp <> nil then
  393.                                 with lsp^ do
  394.                                     if form = subrange then
  395.                                         if rangetype <> nil then
  396.                                             if rangetype = realptr then
  397.                                                 error(399)
  398.                                             else if min.ival > max.ival then
  399.                                                 error(102)
  400.                         end;
  401.                     fsp := lsp;
  402.                     if not (sy in fsys) then
  403.                         begin
  404.                             error(6);
  405.                             skip(fsys)
  406.                         end
  407.                 end
  408.             else
  409.                 fsp := nil
  410.         end; (*simpletype*)
  411.  
  412.         procedure fieldlist (fsys: setofsys; var frecvar: stp);
  413.             var
  414.                 lcp, lcp1, nxt, nxt1: ctp;
  415.                 lsp, lsp1, lsp2, lsp3, lsp4: stp;
  416.                 minsize, maxsize, lsize: addrrange;
  417.                 lvalu: valu;
  418.         begin
  419.             nxt1 := nil;
  420.             lsp := nil;
  421.             if not (sy in (fsys + [ident, casesy])) then
  422.                 begin
  423.                     error(19);
  424.                     skip(fsys + [ident, casesy])
  425.                 end;
  426.             while sy = ident do
  427.                 begin
  428.                     nxt := nxt1;
  429.                     repeat
  430.                         if sy = ident then
  431.                             begin
  432.                                 new(lcp, field);
  433.                                 with lcp^ do
  434.                                     begin
  435.                                         name := id;
  436.                                         idtype := nil;
  437.                                         next := nxt;
  438.                                         klass := field
  439.                                     end;
  440.                                 nxt := lcp;
  441.                                 enterid(lcp);
  442.                                 insymbol
  443.                             end
  444.                         else
  445.                             error(2);
  446.                         if not (sy in [comma, colon]) then
  447.                             begin
  448.                                 error(6);
  449.                                 skip(fsys + [comma, colon, semicolon, casesy])
  450.                             end;
  451.                         test := sy <> comma;
  452.                         if not test then
  453.                             insymbol
  454.                     until test;
  455.                     if sy = colon then
  456.                         insymbol
  457.                     else
  458.                         error(5);
  459.                     typ(fsys + [casesy, semicolon], lsp, lsize);
  460.                     while nxt <> nxt1 do
  461.                         with nxt^ do
  462.                             begin
  463.                                 align(lsp, displ);
  464.                                 idtype := lsp;
  465.                                 fldaddr := displ;
  466.                                 nxt := next;
  467.                                 displ := displ + lsize
  468.                             end;
  469.                     nxt1 := lcp;
  470.                     while sy = semicolon do
  471.                         begin
  472.                             insymbol;
  473.                             if not (sy in fsys + [ident, casesy, semicolon]) then
  474.                                 begin
  475.                                     error(19);
  476.                                     skip(fsys + [ident, casesy])
  477.                                 end
  478.                         end
  479.                 end; (*while*)
  480.             nxt := nil;
  481.             while nxt1 <> nil do
  482.                 with nxt1^ do
  483.                     begin
  484.                         lcp := next;
  485.                         next := nxt;
  486.                         nxt := nxt1;
  487.                         nxt1 := lcp
  488.                     end;
  489.             if sy = casesy then
  490.                 begin
  491.                     new(lsp, tagfld);
  492.                     with lsp^ do
  493.                         begin
  494.                             tagfieldp := nil;
  495.                             fstvar := nil;
  496.                             form := tagfld
  497.                         end;
  498.                     frecvar := lsp;
  499.                     insymbol;
  500.                     if sy = ident then
  501.                         begin
  502.                             new(lcp, field);
  503.                             with lcp^ do
  504.                                 begin
  505.                                     name := id;
  506.                                     idtype := nil;
  507.                                     klass := field;
  508.                                     next := nil;
  509.                                     fldaddr := displ
  510.                                 end;
  511.                             enterid(lcp);
  512.                             insymbol;
  513.                             if sy = colon then
  514.                                 insymbol
  515.                             else
  516.                                 error(5);
  517.                             if sy = ident then
  518.                                 begin
  519.                                     searchid([types], lcp1);
  520.                                     lsp1 := lcp1^.idtype;
  521.                                     if lsp1 <> nil then
  522.                                         begin
  523.                                             align(lsp1, displ);
  524.                                             lcp^.fldaddr := displ;
  525.                                             displ := displ + lsp1^.size;
  526.                                             if (lsp1^.form <= subrange) or isString(lsp1) then
  527.                                                 begin
  528.                                                     if comptypes(realptr, lsp1) then
  529.                                                         error(109)
  530.                                                     else if isString(lsp1) then
  531.                                                         error(399);
  532.                                                     lcp^.idtype := lsp1;
  533.                                                     lsp^.tagfieldp := lcp;
  534.                                                 end
  535.                                             else
  536.                                                 error(110);
  537.                                         end;
  538.                                     insymbol;
  539.                                 end
  540.                             else
  541.                                 begin
  542.                                     error(2);
  543.                                     skip(fsys + [ofsy, lparent])
  544.                                 end
  545.                         end
  546.                     else
  547.                         begin
  548.                             error(2);
  549.                             skip(fsys + [ofsy, lparent])
  550.                         end;
  551.                     lsp^.size := displ;
  552.                     if sy = ofsy then
  553.                         insymbol
  554.                     else
  555.                         error(8);
  556.                     lsp1 := nil;
  557.                     minsize := displ;
  558.                     maxsize := displ;
  559.                     repeat
  560.                         lsp2 := nil;
  561.                         if not (sy in fsys + [semicolon]) then
  562.                             begin
  563.                                 repeat
  564.                                     Bconstant(fsys + [comma, colon, lparent], lsp3, lvalu);
  565.                                     if lsp^.tagfieldp <> nil then
  566.                                         if not comptypes(lsp^.tagfieldp^.idtype, lsp3) then
  567.                                             error(111);
  568.                                     new(lsp3, variant);
  569.                                     with lsp3^ do
  570.                                         begin
  571.                                             nxtvar := lsp1;
  572.                                             subvar := lsp2;
  573.                                             varval := lvalu;
  574.                                             form := variant
  575.                                         end;
  576.                                     lsp4 := lsp1;
  577.                                     while lsp4 <> nil do
  578.                                         with lsp4^ do
  579.                                             begin
  580.                                                 if varval.ival = lvalu.ival then
  581.                                                     error(178);
  582.                                                 lsp4 := nxtvar
  583.                                             end;
  584.                                     lsp1 := lsp3;
  585.                                     lsp2 := lsp3;
  586.                                     test := sy <> comma;
  587.                                     if not test then
  588.                                         insymbol
  589.                                 until test;
  590.                                 if sy = colon then
  591.                                     insymbol
  592.                                 else
  593.                                     error(5);
  594.                                 if sy = lparent then
  595.                                     insymbol
  596.                                 else
  597.                                     error(9);
  598.                                 fieldlist(fsys + [rparent, semicolon], lsp2);
  599.                                 if displ > maxsize then
  600.                                     maxsize := displ;
  601.                                 while lsp3 <> nil do
  602.                                     begin
  603.                                         lsp4 := lsp3^.subvar;
  604.                                         lsp3^.subvar := lsp2;
  605.                                         lsp3^.size := displ;
  606.                                         lsp3 := lsp4
  607.                                     end;
  608.                                 if sy = rparent then
  609.                                     begin
  610.                                         insymbol;
  611.                                         if not (sy in fsys + [semicolon]) then
  612.                                             begin
  613.                                                 error(6);
  614.                                                 skip(fsys + [semicolon])
  615.                                             end
  616.                                     end
  617.                                 else
  618.                                     error(4);
  619.                             end;
  620.                         test := sy <> semicolon;
  621.                         if not test then
  622.                             begin
  623.                                 displ := minsize;
  624.                                 insymbol
  625.                             end
  626.                     until test;
  627.                     displ := maxsize;
  628.                     lsp^.fstvar := lsp1;
  629.                 end
  630.             else
  631.                 frecvar := nil
  632.         end; (*fieldlist*)
  633.  
  634.     begin (*typ*)
  635.         if not (sy in typebegsys) then
  636.             begin
  637.                 error(10);
  638.                 skip(fsys + typebegsys)
  639.             end;
  640.         if sy in typebegsys then
  641.             begin
  642.                 if sy in simptypebegsys then
  643.                     simpletype(fsys, fsp, fsize)
  644.                 else
  645.     (*^*)
  646.                     if sy = arrow then
  647.                         begin
  648.                             new(lsp, pointer);
  649.                             fsp := lsp;
  650.                             with lsp^ do
  651.                                 begin
  652.                                     eltype := nil;
  653.                                     size := ptrsize;
  654.                                     form := pointer
  655.                                 end;
  656.                             insymbol;
  657.                             if sy = ident then
  658.                                 begin
  659.                                     prterr := false; (*no error if search not successful*)
  660.                                     searchid([types], lcp);
  661.                                     prterr := true;
  662.                                     if lcp = nil then   (*forward referenced type id*)
  663.                                         begin
  664.                                             new(lcp, types);
  665.                                             with lcp^ do
  666.                                                 begin
  667.                                                     name := id;
  668.                                                     idtype := lsp;
  669.                                                     next := fwptr;
  670.                                                     klass := types
  671.                                                 end;
  672.                                             fwptr := lcp
  673.                                         end
  674.                                     else
  675.                                         begin
  676.                                             if lcp^.idtype <> nil then
  677.                                                 if lcp^.idtype^.form = files then
  678.                                                     error(108)
  679.                                                 else
  680.                                                     lsp^.eltype := lcp^.idtype
  681.                                         end;
  682.                                     insymbol;
  683.                                 end
  684.                             else
  685.                                 error(2);
  686.                         end
  687.                     else
  688.                         begin
  689.                             if sy = packedsy then
  690.                                 begin
  691.                                     insymbol;
  692.                                     if not (sy in typedels) then
  693.                                         begin
  694.                                             error(10);
  695.                                             skip(fsys + typedels)
  696.                                         end
  697.                                 end;
  698.     (*array*)
  699.                             if sy = arraysy then
  700.                                 begin
  701.                                     insymbol;
  702.                                     if sy = lbrack then
  703.                                         insymbol
  704.                                     else
  705.                                         error(11);
  706.                                     lsp1 := nil;
  707.                                     repeat
  708.                                         new(lsp, arrays);
  709.                                         with lsp^ do
  710.                                             begin
  711.                                                 aeltype := lsp1;
  712.                                                 inxtype := nil;
  713.                                                 form := arrays
  714.                                             end;
  715.                                         lsp1 := lsp;
  716.                                         simpletype(fsys + [comma, rbrack, ofsy], lsp2, lsize);
  717.                                         lsp1^.size := lsize;
  718.                                         if lsp2 <> nil then
  719.                                             if lsp2^.form <= subrange then
  720.                                                 begin
  721.                                                     if lsp2 = realptr then
  722.                                                         begin
  723.                                                             error(109);
  724.                                                             lsp2 := nil
  725.                                                         end
  726.                                                     else if lsp2 = intptr then
  727.                                                         begin
  728.                                                             error(149);
  729.                                                             lsp2 := nil
  730.                                                         end;
  731.                                                     lsp^.inxtype := lsp2
  732.                                                 end
  733.                                             else
  734.                                                 begin
  735.                                                     error(113);
  736.                                                     lsp2 := nil
  737.                                                 end;
  738.                                         test := sy <> comma;
  739.                                         if not test then
  740.                                             insymbol
  741.                                     until test;
  742.                                     if sy = rbrack then
  743.                                         insymbol
  744.                                     else
  745.                                         error(12);
  746.                                     if sy = ofsy then
  747.                                         insymbol
  748.                                     else
  749.                                         error(8);
  750.                                     typ(fsys, lsp, lsize);
  751.                                     repeat
  752.                                         with lsp1^ do
  753.                                             begin
  754.                                                 lsp2 := aeltype;
  755.                                                 aeltype := lsp;
  756.                                                 if inxtype <> nil then
  757.                                                     begin
  758.                                                         getbounds(inxtype, lmin, lmax);
  759.                                                         align(lsp, lsize);
  760.                                                         lsize := lsize * (lmax - lmin + 1);
  761.                                                         size := lsize
  762.                                                     end
  763.                                             end;
  764.                                         lsp := lsp1;
  765.                                         lsp1 := lsp2
  766.                                     until lsp1 = nil
  767.                                 end
  768.                             else
  769.     (*record*)
  770.                                 if sy = recordsy then
  771.                                     begin
  772.                                         insymbol;
  773.                                         oldtop := top;
  774.                                         if top < displimit then
  775.                                             begin
  776.                                                 top := top + 1;
  777.                                                 with display[top] do
  778.                                                     begin
  779.                                                         fname := nil;
  780.                                                         flabel := nil;
  781.                                                         occur := rec
  782.                                                     end
  783.                                             end
  784.                                         else
  785.                                             error(250);
  786.                                         displ := 0;
  787.                                         fieldlist(fsys - [semicolon] + [endsy], lsp1);
  788.                                         new(lsp, records);
  789.                                         with lsp^ do
  790.                                             begin
  791.                                                 fstfld := display[top].fname;
  792.                                                 recvar := lsp1;
  793.                                                 size := displ;
  794.                                                 form := records
  795.                                             end;
  796.                                         top := oldtop;
  797.                                         if sy = endsy then
  798.                                             insymbol
  799.                                         else
  800.                                             error(13)
  801.                                     end
  802.                                 else
  803.     (*set*)
  804.                                     if sy = setsy then
  805.                                         begin
  806.                                             insymbol;
  807.                                             if sy = ofsy then
  808.                                                 insymbol
  809.                                             else
  810.                                                 error(8);
  811.                                             simpletype(fsys, lsp1, lsize);
  812.                                             if lsp1 <> nil then
  813.                                                 if lsp1^.form > subrange then
  814.                                                     begin
  815.                                                         error(115);
  816.                                                         lsp1 := nil
  817.                                                     end
  818.                                                 else if lsp1 = realptr then
  819.                                                     begin
  820.                                                         error(114);
  821.                                                         lsp1 := nil
  822.                                                     end
  823.                                                 else if lsp1 = intptr then
  824.                                                     begin
  825.                                                         error(169);
  826.                                                         lsp1 := nil
  827.                                                     end
  828.                                                 else
  829.                                                     begin
  830.                                                         getbounds(lsp1, lmin, lmax);
  831.                                                         if (lmin < setlow) or (lmax > sethigh) then
  832.                                                             error(169);
  833.                                                     end;
  834.                                             new(lsp, power);
  835.                                             with lsp^ do
  836.                                                 begin
  837.                                                     elset := lsp1;
  838.                                                     size := setsize;
  839.                                                     form := power
  840.                                                 end;
  841.                                         end
  842.                                     else
  843.     (*file*)
  844.                                         if sy = filesy then
  845.                                             begin
  846.                                                 insymbol;
  847.                                                 error(399);
  848.                                                 skip(fsys);
  849.                                                 lsp := nil
  850.                                             end;
  851.                             fsp := lsp
  852.                         end;
  853.                 if not (sy in fsys) then
  854.                     begin
  855.                         error(6);
  856.                         skip(fsys)
  857.                     end
  858.             end
  859.         else
  860.             fsp := nil;
  861.         if fsp = nil then
  862.             fsize := 1
  863.         else
  864.             fsize := fsp^.size
  865.     end; (*typ*)
  866.  
  867.     procedure labeldeclaration (fsys: setofsys); {FIX!!!}
  868.         var
  869.             llp: lbp;
  870.             redef: boolean;
  871.             lbname: integer;
  872.     begin
  873.         repeat
  874.             if sy = intconst then
  875.                 with display[top] do
  876.                     begin
  877.                         llp := flabel;
  878.                         redef := false;
  879.                         while (llp <> nil) and not redef do
  880.                             if llp^.labval <> val.ival then
  881.                                 llp := llp^.nextlab
  882.                             else
  883.                                 begin
  884.                                     redef := true;
  885.                                     error(166)
  886.                                 end;
  887.                         if not redef then
  888.                             begin
  889.                                 new(llp);
  890.                                 with llp^ do
  891.                                     begin
  892.                                         labval := val.ival;
  893.                                         genlabel(lbname);
  894.                                         defined := false;
  895.                                         nextlab := flabel;
  896.                                         labname := lbname
  897.                                     end;
  898.                                 flabel := llp
  899.                             end;
  900.                         insymbol
  901.                     end
  902.             else
  903.                 error(15);
  904.             if not (sy in fsys + [comma, semicolon]) then
  905.                 begin
  906.                     error(6);
  907.                     skip(fsys + [comma, semicolon])
  908.                 end;
  909.             test := sy <> comma;
  910.             if not test then
  911.                 insymbol
  912.         until test;
  913.         if sy = semicolon then
  914.             insymbol
  915.         else
  916.             error(14)
  917.     end; (* labeldeclaration *)
  918.  
  919.     procedure constdeclaration (fsys: setofsys); {FIX!!!}
  920.         var
  921.             lcp: ctp;
  922.             lsp: stp;
  923.             lvalu: valu;
  924.     begin
  925.         if sy <> ident then
  926.             begin
  927.                 error(2);
  928.                 skip(fsys + [ident])
  929.             end;
  930.         while sy = ident do
  931.             begin
  932.                 new(lcp, konst);
  933.                 with lcp^ do
  934.                     begin
  935.                         name := id;
  936.                         idtype := nil;
  937.                         next := nil;
  938.                         klass := konst
  939.                     end;
  940.                 insymbol;
  941.                 if (sy = relop) and (op = eqop) then
  942.                     insymbol
  943.                 else
  944.                     error(16);
  945.                 Bconstant(fsys + [semicolon], lsp, lvalu);
  946.                 enterid(lcp);
  947.                 lcp^.idtype := lsp;
  948.                 lcp^.values := lvalu;
  949.                 if sy = semicolon then
  950.                     begin
  951.                         insymbol;
  952.                         if not (sy in fsys + [ident]) then
  953.                             begin
  954.                                 error(6);
  955.                                 skip(fsys + [ident])
  956.                             end
  957.                     end
  958.                 else
  959.                     error(14)
  960.             end
  961.     end; (*constdeclaration*)
  962.  
  963.     procedure typedeclaration (fsys: setofsys); {FIX!!!}
  964.         var
  965.             lcp, lcp1, lcp2: ctp;
  966.             lsp: stp;
  967.             lsize: addrrange;
  968.     begin
  969.         if sy <> ident then
  970.             begin
  971.                 error(2);
  972.                 skip(fsys + [ident])
  973.             end;
  974.         while sy = ident do
  975.             begin
  976.                 new(lcp, types);
  977.                 with lcp^ do
  978.                     begin
  979.                         name := id;
  980.                         idtype := nil;
  981.                         klass := types
  982.                     end;
  983.                 insymbol;
  984.                 if (sy = relop) and (op = eqop) then
  985.                     insymbol
  986.                 else
  987.                     error(16);
  988.                 typ(fsys + [semicolon], lsp, lsize);
  989.                 enterid(lcp);
  990.                 lcp^.idtype := lsp;
  991.       (*has any forward reference been satisfied:*)
  992.                 lcp1 := fwptr;
  993.                 while lcp1 <> nil do
  994.                     begin
  995.                         if lcp1^.name = lcp^.name then
  996.                             begin
  997.                                 lcp1^.idtype^.eltype := lcp^.idtype;
  998.                                 if lcp1 <> fwptr then
  999.                                     lcp2^.next := lcp1^.next
  1000.                                 else
  1001.                                     fwptr := lcp1^.next;
  1002.                             end
  1003.                         else
  1004.                             lcp2 := lcp1;
  1005.                         lcp1 := lcp1^.next
  1006.                     end;
  1007.                 if sy = semicolon then
  1008.                     begin
  1009.                         insymbol;
  1010.                         if not (sy in fsys + [ident]) then
  1011.                             begin
  1012.                                 error(6);
  1013.                                 skip(fsys + [ident])
  1014.                             end
  1015.                     end
  1016.                 else
  1017.                     error(14)
  1018.             end;
  1019.         if fwptr <> nil then
  1020.             begin
  1021.                 error(117);
  1022.                 WriteLnMessage;
  1023.                 repeat
  1024.                     WriteMessageLine(StringOf(' type-id ', fwptr^.name));
  1025.                     fwptr := fwptr^.next
  1026.                 until fwptr = nil;
  1027.                 if not eol then
  1028.                     WriteMessage(StringOf(' ' : chcnt + 16))
  1029.             end
  1030.     end; (*typedeclaration*)
  1031.  
  1032.     procedure vardeclaration (fsys: setofsys); {FIX!!!}
  1033.         var
  1034.             lcp, nxt: ctp;
  1035.             lsp: stp;
  1036.             lsize: addrrange;
  1037.     begin
  1038.         nxt := nil;
  1039.         repeat
  1040.             repeat
  1041.                 if sy = ident then
  1042.                     begin
  1043.                         new(lcp, vars);
  1044.                         with lcp^ do
  1045.                             begin
  1046.                                 name := id;
  1047.                                 next := nxt;
  1048.                                 klass := vars;
  1049.                                 idtype := nil;
  1050.                                 vkind := actual;
  1051.                                 vlev := level
  1052.                             end;
  1053.                         enterid(lcp);
  1054.                         nxt := lcp;
  1055.                         insymbol;
  1056.                     end
  1057.                 else
  1058.                     error(2);
  1059.                 if not (sy in fsys + [comma, colon] + typedels) then
  1060.                     begin
  1061.                         error(6);
  1062.                         skip(fsys + [comma, colon, semicolon] + typedels)
  1063.                     end;
  1064.                 test := sy <> comma;
  1065.                 if not test then
  1066.                     insymbol
  1067.             until test;
  1068.             if sy = colon then
  1069.                 insymbol
  1070.             else
  1071.                 error(5);
  1072.             typ(fsys + [semicolon] + typedels, lsp, lsize);
  1073.             while nxt <> nil do
  1074.                 with nxt^ do
  1075.                     begin
  1076.                         align(lsp, lc);
  1077.                         idtype := lsp;
  1078.                         vaddr := lc;
  1079.                         lc := lc + lsize;
  1080.                         nxt := next
  1081.                     end;
  1082.             if sy = semicolon then
  1083.                 begin
  1084.                     insymbol;
  1085.                     if not (sy in fsys + [ident]) then
  1086.                         begin
  1087.                             error(6);
  1088.                             skip(fsys + [ident])
  1089.                         end
  1090.                 end
  1091.             else
  1092.                 error(14)
  1093.         until (sy <> ident) and not (sy in typedels);
  1094.         if fwptr <> nil then
  1095.             begin
  1096.                 error(117);
  1097.                 WriteLnMessage;
  1098.                 repeat
  1099.                     WriteMessageLine(StringOf(' type-id ', fwptr^.name));
  1100.                     fwptr := fwptr^.next
  1101.                 until fwptr = nil;
  1102.                 if not eol then
  1103.                     WriteMessage(StringOf(' ' : chcnt + 16))
  1104.             end
  1105.     end; (*vardeclaration*)
  1106.  
  1107. end.